package com.xingkeduo.business.order.domain;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xingkeduo.business.order.remote.HairstyleRemoteService;
import com.xingkeduo.business.order.remote.StoreRemoteService;
import com.xingkeduo.business.order.remote.feign.CommentFeignService;
import com.xingkeduo.business.order.remote.feign.StoreFeignService;
import com.xingkeduo.business.order.service.OrderRefundService;
import com.xingkeduo.business.order.service.OrderService;
import com.xingkeduo.dto.StoreRemoteDto;
import com.xingkeduo.dto.enums.OrderQueryStatus;
import com.xingkeduo.dto.enums.OrderQueryTypeEnum;
import com.xingkeduo.dto.param.HairstyleResponseDTO;
import com.xingkeduo.dto.param.OrderAdminHistoryQueryDto;
import com.xingkeduo.dto.param.OrderAdminQueryDto;
import com.xingkeduo.dto.param.OrderUserQueryDto;
import com.xingkeduo.dto.response.*;
import com.xingkeduo.pojo.enums.OrderStatus;
import com.xingkeduo.pojo.query.OrderDetailMapper;
import com.xingkeduo.pojo.query.OrderMapper;
import com.xingkeduo.pojo.query.OrderRefundMapper;
import com.xingkeduo.pojo.query.OrderStatusLogMapper;
import com.xingkeduo.pojo.table.*;
import com.xingkeduo.util.pojo.exception.BusinessException;
import com.xingkeduo.utils.PageResponseDTO;
import com.xingkeduo.utils.ResponseUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author chi  2019-03-19 15:48
 **/
@Service
public class OrderQueryService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private OrderService orderService;
    @Resource
    private OrderRefundMapper orderRefundMapper;
    @Resource
    private OrderRefundService orderRefundService;
    @Resource
    private HairstyleRemoteService hairstyleRemoteService;
    @Resource
    private StoreRemoteService storeRemoteService;
    @Resource
    private CommentFeignService commentFeignService;
    @Resource
    private OrderStatusLogMapper orderStatusLogMapper;
    @Resource
    private OrderDetailMapper orderDetailMapper;
    @Resource
    private OrderDomainService orderDomainService;

    /**
     * 用户端列表查询
     *
     * @param queryDto
     */
    public PageResponseDTO<OrderUserResponseDto> userQuery(OrderUserQueryDto queryDto) {
        LambdaQueryWrapper<Order> orderLambdaQueryWrapper = orderService.generateUserQuery(queryDto);
        IPage<Order> orderIPage = orderMapper.selectPage(queryDto.getPageObject(), orderLambdaQueryWrapper);
        List<Order> records = orderIPage.getRecords();
        orderDomainService.queryOrdersDetail(records);
        List<OrderUserResponseDto> collect = records.stream()
                .map(orderService::covertToOrderUserResponseDto)
                .collect(Collectors.toList());
        PageResponseDTO<OrderUserResponseDto> dtos = new PageResponseDTO<>(orderIPage, collect);
        return dtos;
    }


    /**
     * 发型师端今日订单,无分页
     *
     * @param queryDto
     * @return
     */
    public List<OrderAdminResponseDto> adminTodayQuery(OrderAdminQueryDto queryDto) {
        LambdaQueryWrapper<Order> orderLambdaQueryWrapper = orderService.generateAdminQuery(queryDto);
        List<Order> orders = orderMapper.selectList(orderLambdaQueryWrapper);
        //补全卡券信息
        orderDomainService.queryOrdersDetail(orders);
        if (orders != null && orders.size() > 0) {
            List<OrderAdminResponseDto> collect = orders.stream()
                    .map(orderService::covertToOrderAdminResponseDto)
                    .collect(Collectors.toList());
            return collect;
        }
        return new ArrayList<>();
    }


    public OrderAdminResponseDto getAdminOrder(String orderNo) {
        Order order = orderMapper.selectOne(new QueryWrapper<Order>().lambda().eq(Order::getOrderNo, orderNo).last("LIMIT 1"));
        if(order==null){
            throw new BusinessException(BusinessException.Type.DEFAULT,"订单不存在");
        }
        orderService.supplementOrder(order);
        OrderAdminResponseDto orderAdminResponseDto = orderService.covertToOrderAdminResponseDto(order);
        return orderAdminResponseDto;
    }


    /**
     * 发型师端历史订单查询,带分页
     *
     * @param queryDto
     * @return
     */
    public PageResponseDTO<OrderAdminResponseDto> adminHistoryQuery(OrderAdminHistoryQueryDto queryDto, OrderQueryTypeEnum orderQueryTypeEnum) {
        if (OrderQueryTypeEnum.REFUND.equals(orderQueryTypeEnum)) {
            return adminHistoryQueryRefund(queryDto);
        }

        IPage<Order> page = new Page<>(queryDto.getPageNo(), queryDto.getPageSize());
        LambdaQueryWrapper<Order> orderLambdaQueryWrapper = orderService.generateAdminHistoryQuery(queryDto, orderQueryTypeEnum);
        IPage<Order> orderIPage = orderMapper.selectPage(page, orderLambdaQueryWrapper);
        List<Order> records = orderIPage.getRecords();
        orderDomainService.queryOrdersDetail(records);
        List<OrderAdminResponseDto> collect = records.stream()
                .map(orderService::covertToOrderAdminResponseDto)
                .peek(orderRefundService::peekOrderAdminResponseDto)
                .collect(Collectors.toList());
        PageResponseDTO<OrderAdminResponseDto> dtos = new PageResponseDTO<>(orderIPage, collect);
        return dtos;
    }


    //TODO 待优化
    private PageResponseDTO<OrderAdminResponseDto> adminHistoryQueryRefund(OrderAdminHistoryQueryDto queryDto) {

        LambdaQueryWrapper<OrderRefund> orderRefundLambdaQueryWrapper = orderService.generateAdminHistoryQueryRefund(queryDto);

        IPage<OrderRefund> page = new Page<>(queryDto.getPageNo(), queryDto.getPageSize());
        IPage<OrderRefund> orderIPage = orderRefundMapper.selectPage(page, orderRefundLambdaQueryWrapper);
        List<OrderRefund> records = orderIPage.getRecords();

        List<OrderAdminResponseDto> collect1 = records.stream().map(orderRefund -> {
            Order order = orderMapper.selectById(orderRefund.getOrderId());
            orderService.supplementOrder(order);
            return order;
        }).map(orderService::covertToOrderAdminResponseDto)
                .peek(orderRefundService::peekOrderAdminResponseDto)
                .collect(Collectors.toList());
        PageResponseDTO<OrderAdminResponseDto> dtos = new PageResponseDTO<>(orderIPage, collect1);
        return dtos;
    }

    /**
     * 查看正在服务的订单
     *
     * @param adminId
     * @return
     */
    public OrderAdminResponseDto inServiceQuery(String adminId) {
        Order order = orderMapper.selectOne(new QueryWrapper<Order>().lambda().eq(Order::getStatus, OrderStatus.IN_SERVICE).eq(Order::getAdminId, adminId).last("LIMIT 1"));
        orderService.supplementOrder(order);
        OrderAdminResponseDto orderAdminResponseDto = orderService.covertToOrderAdminResponseDto(order);
        return orderAdminResponseDto;
    }


    /**
     * 发型师端订单详情
     *
     * @param id
     * @return
     */
    public OrderAdminDetailResponseDto adminDetail(String id,String orderNo) {
        Order order = null;

        if(StringUtils.isNotBlank(id)){
            order = orderService.getOrderById(id);
        }else if(StringUtils.isNotBlank(orderNo)){
            order = orderService.queryOrder(orderNo);
        }else {
            throw new BusinessException(BusinessException.Type.DEFAULT, "参数错误");
        }

        if(order==null){
            throw new BusinessException(BusinessException.Type.DEFAULT, "订单不存在");
        }


        OrderAdminResponseDto orderAdminResponseDto = orderService.covertToOrderAdminResponseDto(order);
        OrderAdminDetailResponseDto dto = new OrderAdminDetailResponseDto();
        BeanUtils.copyProperties(orderAdminResponseDto, dto);


        OrderDetail orderDetail = orderDetailMapper.selectOne(new QueryWrapper<OrderDetail>().lambda().eq(OrderDetail::getOrderNo, order.getOrderNo()).last("LIMIT 1"));
        if (orderDetail != null) {
            List<LocalDateTime> times = orderDetail.announceCountlist();
            if (times.size() > 0) {
                dto.setFirstAnnounceTime(times.get(0));
                dto.setLastAnnounceTime(times.get(times.size() - 1));
            }
        }


        if (OrderStatus.IN_SERVICE.equals(order.getStatus())) {
            dto.setServeLastSeconds(Duration.between(order.getServeStartTime(), LocalDateTime.now()).getSeconds());
        }


        //查询发型库
        if (order.getHairId() > 0) {
            HairstyleResponseDTO byHairId = hairstyleRemoteService.getByHairId(Long.valueOf(order.getHairId()));
            dto.setOrderHair(byHairId);
        }

        //查询退款信息
        Optional<OrderRefund> refundOptional = orderRefundService.getRefundById(id);
        refundOptional.ifPresent(orderRefund -> {
            OrderRefundResponseDto orderRefundResponseDto = orderRefundService.covertDto(orderRefund);
            dto.setOrderRefund(orderRefundResponseDto);
        });

        if (order.getHadComment() != null && order.getHadComment()) {
            //记录评论时间
            ResponseUtils<Comments> responseUtils = commentFeignService.queryDetailByorderId(order.getId());
            if (responseUtils.success()) {
                dto.setCommentTime(responseUtils.getData().getCreatedTime());
            }
        }


        if (OrderStatus.OVER_NUMBER.equals(order.getStatus())) {

            OrderStatusLog orderStatusLog = orderStatusLogMapper.selectOne(new QueryWrapper<OrderStatusLog>().lambda().eq(OrderStatusLog::getOrderId, order.getId())
                    .eq(OrderStatusLog::getNewStatus, OrderStatus.OVER_NUMBER).last("LIMIT 1"));
            if (orderStatusLog != null) {
                dto.setOverNumberTime(orderStatusLog.getCreatedTime());
            }
        }

        if (OrderStatus.REFUND_DONE.equals(order.getStatus())) {

            OrderStatusLog orderStatusLog = orderStatusLogMapper.selectOne(new QueryWrapper<OrderStatusLog>().lambda().eq(OrderStatusLog::getOrderId, order.getId())
                    .eq(OrderStatusLog::getNewStatus, OrderStatus.REFUND_DONE).last("LIMIT 1"));
            if (orderStatusLog != null) {
                dto.setRefundSuccessTime(orderStatusLog.getCreatedTime());
            }
        }

        return dto;
    }

    public HashMap<OrderQueryStatus, Integer> getTodayCount(String adminId, String storeId) {
        OrderAdminQueryDto orderAdminQueryDto = new OrderAdminQueryDto();
        orderAdminQueryDto.setAdminId(adminId);
        orderAdminQueryDto.setStoreId(storeId);
        HashMap<OrderQueryStatus, Integer> map = new HashMap<>();


        orderAdminQueryDto.setOrderQueryStatus(OrderQueryStatus.PAID);
        LambdaQueryWrapper<Order> orderLambdaQueryWrapper = orderService.generateAdminQuery(orderAdminQueryDto);
        Integer integer = orderMapper.selectCount(orderLambdaQueryWrapper);
        map.put(orderAdminQueryDto.getOrderQueryStatus(), integer);


        orderAdminQueryDto.setOrderQueryStatus(OrderQueryStatus.SERVICE_DOWN);
        LambdaQueryWrapper<Order> orderLambdaQueryWrapper1 = orderService.generateAdminQuery(orderAdminQueryDto);
        Integer integer1 = orderMapper.selectCount(orderLambdaQueryWrapper1);
        map.put(orderAdminQueryDto.getOrderQueryStatus(), integer1);


        orderAdminQueryDto.setOrderQueryStatus(OrderQueryStatus.REFUND_OVERNUMBER);
        LambdaQueryWrapper<Order> orderLambdaQueryWrapper2 = orderService.generateAdminQuery(orderAdminQueryDto);
        Integer integer2 = orderMapper.selectCount(orderLambdaQueryWrapper2);
        map.put(orderAdminQueryDto.getOrderQueryStatus(), integer2);


        map.put(OrderQueryStatus.ALL, integer + integer2 + integer1);

        return map;
    }


    /**
     * 查询店铺详情
     *
     * @param id
     * @return
     */
    public OrderUserDetailResponseDto userDetailQuery(String id) {
        OrderUserDetailResponseDto orderUserResponseDto = new OrderUserDetailResponseDto();
        Order order = orderService.getOrderById(id);
        BeanUtils.copyProperties(order, orderUserResponseDto);
        StoreRemoteDto byStoreId = storeRemoteService.getByStoreId(id);
        if (byStoreId != null) {
            BeanUtils.copyProperties(byStoreId, orderUserResponseDto);
        }
        return orderUserResponseDto;
    }

}
